package com.iotimc.attendancesystem.attendance;

import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import com.iotimc.attendancesystem.App;
import com.iotimc.attendancesystem.Contract;
import com.iotimc.attendancesystem.dao.AttendanceLogEntityDao;
import com.iotimc.attendancesystem.dao.DoorLogEntityDao;
import com.iotimc.attendancesystem.dao.GreenDaoManager;
import com.iotimc.attendancesystem.dao.PersonEntityDao;
import com.iotimc.attendancesystem.entity.AttendanceLogEntity;
import com.iotimc.attendancesystem.entity.BasicSettingEntity;
import com.iotimc.attendancesystem.entity.DoorLogEntity;
import com.iotimc.attendancesystem.entity.PersonEntity;
import com.iotimc.attendancesystem.io.CardCommonPresenter;
import com.iotimc.attendancesystem.io.IoCommonPresenter;
import com.iotimc.attendancesystem.util.ShareUtil;
import com.iotimc.attendancesystem.util.TtsUtil;
import com.pefis.natives.Ast2600JNI;
import com.pefis.natives.PfsBioInfo;
import com.pefis.view.FaceDetectionView;

import org.greenrobot.greendao.query.QueryBuilder;

import java.io.ByteArrayOutputStream;
import java.util.Date;
import java.util.List;

/**
 * @author david
 * @date 2017/11/27
 */

public class AttendancePresenter implements AttendanceContract.Presenter {
    private static final String TAG = "AttendancePresenter";
    FaceDetectionView mFaceDetectionView;
    boolean mLoop;
    byte[] mColorImageFrame;
    byte[] mProcessImageFrame;
    byte[] m_Template;
    int mImageWidth;
    int mImageHeight;
    public byte[] m_UpdateTemplate;
    private long[] mCandInfo;
    private byte[] mPhotoImage;
    Handler handler = new Handler(Looper.getMainLooper());
    AttendanceContract.View view;
    PersonEntityDao personEntityDao;
    AttendanceLogEntityDao attendanceLogEntityDao;
    DoorLogEntityDao doorLogEntityDao;
    BasicSettingEntity entity;
    boolean checkAdmin = false;
    private long time = 0;

    public AttendancePresenter(AttendanceContract.View view) {
        this.view = view;
        entity = App.getInstance().getBasicSettingEntity();
        mImageWidth = PfsBioInfo.getInstance().face_img_w[0];
        mImageHeight = PfsBioInfo.getInstance().face_img_h[0];
        mColorImageFrame = new byte[mImageWidth * mImageHeight];
        mProcessImageFrame = new byte[mImageWidth * mImageHeight];
        m_Template = new byte[PfsBioInfo.getInstance().enroll_template_size[0]];
        m_UpdateTemplate = new byte[PfsBioInfo.getInstance().enroll_template_size[0]];
        mCandInfo = new long[PfsBioInfo.PFSBIO_CAND_STRUCT];
        mPhotoImage = new byte[mImageWidth * mImageHeight * 4];
        personEntityDao = GreenDaoManager.getInstance().getSession().getPersonEntityDao();
        attendanceLogEntityDao = GreenDaoManager.getInstance().getSession().getAttendanceLogEntityDao();
        doorLogEntityDao = GreenDaoManager.getInstance().getSession().getDoorLogEntityDao();
    }

    @Override
    public void setmFaceDetectionView(AttendanceContract.View view, FaceDetectionView mFaceDetectionView) {
        this.mFaceDetectionView = mFaceDetectionView;
        this.view = view;
    }

    private Runnable runnable = new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            int vnRet;
            int[] update_tmpl_flag = new int[1];
            int[] identified_id = new int[1];
            Ast2600JNI.getInstance().pisFcInfraredLedControl(
                    PfsBioInfo.getInstance().mContextID,
                    PfsBioInfo.PFSBIO_IR_LED_HIGH_ON);
            short[] faceRect = new short[4];
            while (mLoop) {
                Ast2600JNI.getInstance().pisFcColorImageCapture(
                        PfsBioInfo.getInstance().mContextID, mColorImageFrame);
                Ast2600JNI.getInstance().pisFcGrayImageCapture(
                        PfsBioInfo.getInstance().mContextID, mProcessImageFrame);

                PfsBioInfo.getInstance().CreateColorBitmapFromBayer(
                        mColorImageFrame);
                if (view != null) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            view.showImage(PfsBioInfo.getInstance().m_bmp);
                        }
                    });
                }
                vnRet = Ast2600JNI.getInstance().pisFcCheck(
                        PfsBioInfo.getInstance().mContextID, mProcessImageFrame,
                        mImageWidth, mImageHeight, faceRect);
                if (vnRet != PfsBioInfo.PFSBIO_OK) {
                    Ast2600JNI.getInstance().pisLedControl(
                            PfsBioInfo.getInstance().mContextID,
                            PfsBioInfo.PFSBIO_OKNOLED, PfsBioInfo.PFSBIO_LED_OFF);

                    mFaceDetectionView.setRect(-10, -10, -10, -10);
                    mFaceDetectionView.postInvalidate();
                    continue;
                }
                double left = faceRect[0]*1.35,top = faceRect[2]*1.1;

                mFaceDetectionView.setRect((int) left, (int) top, faceRect[1]
                        - faceRect[0], faceRect[3] - faceRect[2]);
                mFaceDetectionView.postInvalidate();

                vnRet = Ast2600JNI.getInstance().pisFcIdentify(
                        PfsBioInfo.getInstance().mContextID, mProcessImageFrame,
                        mImageWidth, mImageHeight, identified_id, mCandInfo,
                        m_UpdateTemplate, update_tmpl_flag);
                if (vnRet == PfsBioInfo.PFSBIO_OK) {
                    if (mCandInfo[5] >= entity.getSimilarityScore()) {
                        Ast2600JNI.getInstance().pisLedControl(
                                PfsBioInfo.getInstance().mContextID,
                                PfsBioInfo.PFSBIO_OKLED, PfsBioInfo.PFSBIO_LED_ON);
                        if (update_tmpl_flag[0] == 1) {
                            PfsBioInfo.getInstance().WriteByteToFile(
                                    m_UpdateTemplate,
                                    PfsBioInfo.TEMPLATE_DB_PATH + identified_id[0]);
                        }
                        // 人脸对比成功后操作 成功后 播放语音
                        Log.i(TAG, "identified_id[0]" + identified_id[0]);

                        PersonEntity personEntity = personEntityDao.queryBuilder()
                                .where(PersonEntityDao.Properties.ICodeId.eq(identified_id[0])).unique();
                        if (personEntity != null) {
                            if (checkAdmin) {
                                view.showUser(personEntity, true);
                            } else {
                                quickValidate(personEntity);
                            }
                        }
                    }
                } else {
                   /* if (time == 0 || System.currentTimeMillis() - time > 1000) {
                        if (checkFailCount(System.currentTimeMillis())) {
                            time = System.currentTimeMillis();
                            TtsUtil.ttsSpeek2("验证失败！");
                        }
                    }*/

                    view.resetUser();

                /*    Ast2600JNI.getInstance().pisLedControl(
                            PfsBioInfo.getInstance().mContextID,
                            PfsBioInfo.PFSBIO_NOLED, PfsBioInfo.PFSBIO_LED_ON);*/


                }

            }

            /*Ast2600JNI.getInstance().pisFcInfraredLedControl(
                    PfsBioInfo.getInstance().mContextID,
                    PfsBioInfo.PFSBIO_IR_LED_OFF);*/
           /* Ast2600JNI.getInstance().pisLedControl(
                    PfsBioInfo.getInstance().mContextID,
                    PfsBioInfo.PFSBIO_NOLED, PfsBioInfo.PFSBIO_LED_OFF);*/

        }
    };

    private AsyncTask asyncTask;
    private int checkCount;
    private long currentTime;

    private boolean checkCount(long currentTime) {
        if (currentTime - this.currentTime > 3000) {
            Log.i(TAG, "accept: checkCount" + "=============" + checkCount);
            checkCount += 1;
            if (checkCount > 4) {
                view.showUser(null, false);
                return false;
            } else {
                this.currentTime = currentTime;
                return true;
            }
        }
        return false;
    }

    private int checkFailCount;
    private long currentFailTime;

    private boolean checkFailCount(long currentTime) {
        if (currentTime - this.currentFailTime > 3000) {
            Log.i(TAG, "accept: checkFailCount" + "=====Fail========" + checkFailCount);
            checkFailCount += 1;
            if (checkFailCount > 4) {
                view.showUser(null, false);
                return false;
            } else {
                this.currentFailTime = currentTime;
                return true;
            }
        }
        Log.i(TAG, "accept: checkFailCount" + "======true=======" + checkFailCount);
        return false;
    }

    @Override
    public void resetCount() {
        checkCount = 0;
        currentTime = 0;
        checkFailCount = 1;
        currentFailTime = 0;
    }

    @Override
    public void setCheckAdmin(boolean admin) {
        this.checkAdmin = admin;
    }

    @Override
    public void startAttendance() {
        mLoop = true;
        Log.i(TAG, "startAttendance: " + mLoop);
        asyncTask = new AsyncTask() {
            @Override
            protected Object doInBackground(Object[] objects) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 判断是否被取消
                if (isCancelled()) {
                    mLoop = false;
                }

                boolean aBoolean = ShareUtil.getBoolean(App.getAppContext(), false, Contract.DEVICE_STATUS);
                if (aBoolean) {
                    runnable.run();
                }

                return null;
            }
        };
        asyncTask.execute(0);
    }

    @Override
    public void stopAttendance() {
        if (mLoop) {
            mLoop = false;
            Log.i(TAG, "stopAttendance: " + mLoop);
            asyncTask.cancel(true);
           /* Ast2600JNI.getInstance().pisLedControl(
                    PfsBioInfo.getInstance().mContextID, PfsBioInfo.PFSBIO_OKNOLED,
                    PfsBioInfo.PFSBIO_LED_OFF);*/
        }
    }

    @Override
    public boolean isRuning() {
        return mLoop;
    }

    /**
     * 不需要验证间隔时间时间
     */
    private void quickValidate(PersonEntity personEntity) {
        Date date = new Date();
        date.setTime(date.getTime() - (entity.getTime() * 1000));
        QueryBuilder queryBuilder = attendanceLogEntityDao.queryBuilder();
        queryBuilder.where(AttendanceLogEntityDao.Properties.PersonId.eq(personEntity.getId())
                , AttendanceLogEntityDao.Properties.CreateTime.ge(date));
        List<AttendanceLogEntity> entities = queryBuilder.list();
        //间隔时间内只有保留一条记录
        if (entities.size() == 0) {
            attendanceLogEntityDao.insert(new AttendanceLogEntity(null,
                    personEntity.getId(), null, new Date()));
        }
        if (entity.getDeviceType() == BasicSettingEntity.DeviceType.AUTO_DOOR) {
            IoCommonPresenter.getInstance().open();
            doorLogEntityDao.insert(new DoorLogEntity(null, personEntity.getId(), new Date()));
        }
        view.showUser(personEntity, true);
        CardCommonPresenter.getInstance().getSoundPool()
                .play(2,1, 1, 0, 0, 1);
        checkCount = 1;
    }


    private void validate(PersonEntity personEntity) {
        Date date = new Date();
        date.setTime(date.getTime() - (entity.getTime() * 1500));
        QueryBuilder queryBuilder = attendanceLogEntityDao.queryBuilder();
        // queryBuilder.join(AttendanceLogEntityDao.Properties.PersonId, PersonEntity.class, PersonEntityDao.Properties.Id).
        queryBuilder.where(AttendanceLogEntityDao.Properties.PersonId.eq(personEntity.getId()), AttendanceLogEntityDao.Properties.CreateTime.ge(date));

        List<AttendanceLogEntity> entities = queryBuilder.list();
        if (entities.size() == 0) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PfsBioInfo.getInstance().m_bmp.compress(Bitmap.CompressFormat.JPEG, 50, baos);
            byte[] capture = baos.toByteArray();
            attendanceLogEntityDao.insert(new AttendanceLogEntity(null, personEntity.getId(), capture, new Date()));
            if (entity.getDeviceType() == BasicSettingEntity.DeviceType.AUTO_DOOR) {
                IoCommonPresenter.getInstance().open();
                doorLogEntityDao.insert(new DoorLogEntity(null, personEntity.getId(), new Date()));
            }
            view.showUser(personEntity, true);
            TtsUtil.ttsSpeek("验证通过！");
            checkCount = 1;
        } else {
            if (checkCount(System.currentTimeMillis())) {
                view.showUser(personEntity, false);
                TtsUtil.ttsSpeek2("请勿重复验证！");
            }
        }
    }

}
